package com.uottawa.librarytest.service;

import static org.junit.Assert.*;

import java.util.Calendar;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.uottawa.library.dao.BaseDAO;
import com.uottawa.library.dao.LoanDAO;
import com.uottawa.library.dao.UserDAO;
import com.uottawa.library.domain.Item;
import com.uottawa.library.domain.Loan;
import com.uottawa.library.domain.LoanPeriod;
import com.uottawa.library.domain.User;
import com.uottawa.library.service.LoanPeriodService;
import com.uottawa.library.service.LoanService;
import com.uottawa.library.service.UserService;

public class UserServiceTest {

	private UserService userService;
	private LoanService loanService;
	
	@Before
	public void setUp() throws Exception {
		userService = new UserService();
		loanService = new LoanService();
	}

	@After
	public void tearDown() throws Exception {
		new BaseDAO().cleanUp();
	}
	
	@Test
	public void testAddUserSuccesfully() {
		User user = new User(0, "OkUser", "password", 0, "user");;
		String result = userService.addUser(user);
		assertEquals("success", result);
	}
	
	@Test
	public void testAddTwoUsersSuccessfully(){
		User user1 = new User(0, "user1", "user1pass", 0, "user");
		String result1 = userService.addUser(user1);
		User user2 = new User(1, "user2", "user2pass", 0, "user");
		String result2 = userService.addUser(user2);
		assertTrue(result2.equals(result1));
	}
	
	
	
	@Test
	public void testAddDuplicateUser() {
		User user = new User(0, "OkUser", "password", 0, "user");
		userService.addUser(user);
		// retrieve user from DB to get the auto generated id.
		user = userService.login("OkUser", "password");
		// add the same user again, expect error message.
		String result = userService.addUser(user);
		assertEquals("failed, duplicate entry", result);
	}
	
	@Test
	public void testDeleteUserSuccessfully() {
		User user =  new User(0, "OkUser", "password", 0, "user");;
		userService.addUser(user);
		String result = userService.deleteUser(user);
		assertEquals("success", result);
	}
	
	@Test
	public void testDeleteUserWithLateFees() {
		
		UserDAO userDao = new UserDAO();
		LoanDAO loanDAO = new LoanDAO(); 
		User regularUser = new User(623, "UserWithExpiryDate", "password", 0, "user");
		User user =  new User(1111, "admin", "password", 0, "admin");
		userDao.addUser(user);		
		userDao.addUser(regularUser);
		
		regularUser = userDao.getUser("UserWithExpiryDate", "password");
		user = userDao.getUser("admin", "password");
		
		LoanPeriod loanPeriod = new LoanPeriod(1,5);
		LoanPeriodService loanPeriodService = new LoanPeriodService();
		loanPeriodService.addPeriod(loanPeriod, user);
		Item item = new Item();
		item.setItemId(1020);
		loanService.borrowLoanCopy(item, regularUser);
		// update loan to have expaied date
		Loan loan = loanDAO.getLoanByItemId(item.getItemId());
		java.util.Date currentDate = Calendar.getInstance().getTime(); // current date of now 
		currentDate.setHours(currentDate.getHours() - 3 );
		loan.setExpiryDate(new java.sql.Timestamp(currentDate.getTime()));
		loanDAO.updateLoan(loan);
		//return item
		loanService.returnLoan(loan);
		
		String result = userService.deleteUser(regularUser);
		assertEquals("failed, outstanding balance", result);
	}
	
	@Test
	public void testDeleteUserWithActiveLoansOrRenewals() {
		//create user
		User adminUser =  new User(13243, "admin", "password", 0, "admin");;

		User user =  new User(12, "user", "password", 0, "user");;
		userService.addUser(user);
		userService.addUser(adminUser);
		
		// create an item
		Item item = new Item();
		item.setItemId(6666);	
		
		LoanPeriod loanPeriod = new LoanPeriod(1,5);
		LoanPeriodService loanPeriodService = new LoanPeriodService();
		loanPeriodService .addPeriod(loanPeriod, adminUser);

		loanService.borrowLoanCopy(item, user);		
		String result = userService.deleteUser(user);
		
		assertEquals("failed, user has active loans", result);
	}

}
